package com.tian.view.draw.advance

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.graphics.Rect
import android.graphics.RectF
import android.graphics.Region
import android.graphics.RegionIterator
import android.util.AttributeSet
import android.view.View
import android.view.animation.LinearInterpolator
import com.tian.util.view.DisplayUtil
import com.tian.view.draw.region.RegionView

/**
 * @author tiansongtao
 * @date 2023/1/4 14:21
 *
 * Pierre Bezier 贝塞尔曲线
 * 这种曲线很顺滑， 具体详细数学公式可网上查找
 *
 * 贝塞尔曲线需要三个点构建， 起始点，终止点 控制点
 *
 */
class PierreBezierPathView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
        View(context, attrs, defStyleAttr) {

    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context) : this(context, null)

    val paint = Paint().apply {
        color = Color.RED
        strokeWidth = DisplayUtil.dpToPx(2f)
        style = Paint.Style.STROKE
        isAntiAlias = true
    }
    val textPaint = Paint().apply {
        color = Color.BLACK
        style = Paint.Style.FILL_AND_STROKE
        textSize = DisplayUtil.spToPx(14f)
        isAntiAlias = true
    }

    private var lineWidth = 300f
    private var offX = 0f
    private lateinit var anim: ValueAnimator
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        anim = ValueAnimator.ofFloat(0f, lineWidth)
        anim.duration = 2000
        anim.repeatCount = ValueAnimator.INFINITE
        anim.interpolator = LinearInterpolator()
        anim.addUpdateListener {
            offX = it.animatedValue as Float
            postInvalidate()
        }
        anim.start()
    }


    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawText("贝塞尔曲线", 50f, 50f, textPaint)
        val path = Path()
        path.moveTo(300f, 50f)
        /**
         * 二阶贝塞尔曲线
         * [Path.quadTo] 贝塞尔曲线，参数为两个坐标，x1\y1 控制点坐标 x2\y2终点坐标
         *   贝塞尔曲线需要三个坐标，quadTo的起始坐标就是path路径的起始点或上个路径的终点
         * [Path.rQuadTo] 两个坐标为相对于起始点的坐标，x1=-100 则控制点坐标为 起始点.x + x1
         *
         * 三阶贝塞尔曲线：用法与二阶类似，比较少用
         * [Path.cubicTo]
         * [Path.rCubicTo]
         */
        path.quadTo(350f, 90f, 400f, 50f)
        path.quadTo(450f, 10f, 500f, 50f)
        canvas.drawPath(path, paint)

        canvas.drawText("波浪图", 50f, 120f, textPaint)

        canvas.save()
        canvas.translate(250f, 100f)
        val rectf = RectF(0f, 0f, lineWidth, 100f)
        val halfWidth = lineWidth / 2
        path.reset()
        path.moveTo(-lineWidth + offX, 50f)
        for (i in (-lineWidth).toInt() until (lineWidth * 2).toInt() step lineWidth.toInt()) {
            path.rQuadTo(halfWidth / 2, -50f, halfWidth, 0f)
            path.rQuadTo(halfWidth / 2, 50f, halfWidth, 0f)
        }
        path.lineTo(lineWidth, rectf.bottom)
        path.lineTo(0f, rectf.bottom)
        path.close()
        val path1 = Path()
        path1.addRect(rectf, Path.Direction.CW)

        /**
         * 使用Region来进行显示区域设置, 了解在[RegionView]
         */
        val region1 = Region()
        val region2 = Region()
        region1.setPath(path1, Region(0, 0, lineWidth.toInt(), rectf.bottom.toInt()))
        region2.setPath(path, Region(0, 0, lineWidth.toInt(), rectf.bottom.toInt()))
        region1.op(region2, Region.Op.REPLACE)
        val iter = RegionIterator(region1)
        var rect = Rect()
        paint.style = Paint.Style.FILL_AND_STROKE
        while (iter.next(rect)) {
            canvas.drawRect(rect, paint)
        }
        paint.style = Paint.Style.STROKE

    }
}